#include "abbr_reform.h"
#include "../../util.h"

void AbbrReform::decode(string line, map<string, set<string>> &abbr_model)
{
		int del1 = line.find('\t'), del2 = line.find('>');
		string phrase = line.substr(0, del2);
		string abbr = line.substr(del2 + 1, del1 - del2 - 1);
		map<string, set<string>>::iterator itr = abbr_model.find(phrase);
		if(itr == abbr_model.end())
		{
			set<string> s;
			s.insert(abbr);
			abbr_model.insert(pair<string, set<string>>(phrase, s));
		}else
			(*itr).second.insert(abbr);
}
AbbrReform::AbbrReform(iostream *abbr_file)
{
	string line;
	while(!abbr_file->eof())
	{
		getline(*abbr_file, line);
		decode(line, abbr_model_g);
	}	
}

void AbbrReform::update(string line)
{
	abbr_model_l.clear();
	vector<string> v = util::tokenize_h(line, " | ");
	for(int i = 0; i < v.size(); ++ i)
		decode(v[i], abbr_model_l);
}

string AbbrReform::to_abbr(string query)
{
	vector<string> v = util::tokenize(query, " ");
	vector<string> res_v;
	string res;
	map<string, set<string>>::iterator itr;
	for(int i = 0; i < v.size(); ++ i){
		bool flag = false;
		for(int j = v.size() - 1; j >= i; -- j){
			string prot;
			for(int k = i; k <= j; ++ k){
				prot += v[k];
				prot += " ";
			}
			itr = abbr_model_g.find(prot);
			if(itr != abbr_model_g.end()){
				i = j;
				res_v.push_back(*(*itr).second.begin());
				flag = true;
				break;
			}
			else{
				itr = abbr_model_l.find(prot);
				if(itr != abbr_model_l.end()){
					i = j;
					res_v.push_back(*(*itr).second.begin());
					flag = true;
					break;
				}
			}
		}
		if(!flag)
			res_v.push_back(v[i]);
	}
	for(int i = 0; i < res_v.size(); ++ i){
		res += res_v[i];
		res += " ";
	}
	return util::format(res);

}

void AbbrReform::reform(QueryNode &node)
{
	string res_by_corr = to_abbr(node.name);
	string res_by_label = to_abbr(node.label);
	node.label = (res_by_label.length() > res_by_corr.length())?res_by_corr:res_by_label;
}

QueryNode AbbrReform::reform_new(QueryNode &node)
{
	string res_by_corr = to_abbr(node.name);
	string res_by_label = to_abbr(node.label);
	string res_l = (res_by_corr.length() > res_by_label.length())?res_by_label:res_by_corr;
	QueryNode res(to_abbr(res_l));
	res.isVirtual = true;
	return res;
}